package com.geese.common.oss;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.sql.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.google.common.collect.Maps;

@Service
public class DefaultOssClientManager implements OssClientManager {
	
	private static final Long POLICY_EXPIRE_TIME = 2 * 60L;  
	
	private Credentials credential ;
	private OSSClient ossClient ;
	
	@Autowired
	public DefaultOssClientManager(OSSClient ossClient){
		this.ossClient = ossClient;
		this.credential = ossClient.getCredentialsProvider().getCredentials();
	}
	
	@Override
	public Map<String, Object> getPolicy(String bucket, PolicyConditions policyConds) {
		return getPolicy(bucket, null, POLICY_EXPIRE_TIME, policyConds);
	}
	
	@Override
	public Map<String, Object> getPolicy(String bucket, long expireTime, PolicyConditions policyConds) {
		return getPolicy(bucket, null, expireTime, policyConds);
	}
	
	@Override
	public Map<String, Object> getPolicy(String bucket, String dir, PolicyConditions policyConds) {
		return getPolicy(bucket, dir, POLICY_EXPIRE_TIME, policyConds);
	}

	@Override
	public Map<String, Object> getPolicy(String bucket, String dir, long expireTime, PolicyConditions policyConds) {
		long tempExpireTime = expireTime;
		if (tempExpireTime < 0L) {
			tempExpireTime = POLICY_EXPIRE_TIME ;
		}
		StringBuilder builderHost = new StringBuilder();
		builderHost.append("http://").append(bucket).append(".").append(ossClient.getEndpoint().getHost());
    	long expireEndTime = System.currentTimeMillis() + tempExpireTime * 1000;
    	
    	PolicyConditions tempPolicyConds = policyConds;
    	if (!StringUtils.isEmpty(dir)) {
    		tempPolicyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
    	}
    	
        String postPolicy = ossClient.generatePostPolicy(new Date(expireEndTime), tempPolicyConds);
		String encodedPolicy = BinaryUtil.toBase64String(postPolicy.getBytes(Charset.forName("UTF-8")));
        String postSignature = ossClient.calculatePostSignature(postPolicy);
        
        Map<String, Object> respMap = Maps.newLinkedHashMap();
        respMap.put("accessid", credential.getAccessKeyId());
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", StringUtils.isEmpty(dir) ? "" : dir);
        respMap.put("host", builderHost.toString());
        respMap.put("expire", String.valueOf(expireEndTime / 1000));
        return respMap;
	}

	@Override
	public void upload(String bucket, String key, InputStream inputStream) {
		ossClient.putObject(bucket, key, inputStream);
	}
	
}
